home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 1996 June / Software of the Month Club 1996 June.iso / pc / dos / dtp / display / drvsrc / s3864_2m.asm < prev    next >
Assembly Source File  |  1994-12-21  |  17KB  |  569 lines

  1. ;--------------------------------------------------------------------------
  2. ; This is file VESA_S3.ASM
  3. ;
  4. ; Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
  5. ; Copyright (C) 1992 Csaba Biegl, 820 Stirrup Dr, Nashville, TN 37221
  6. ; Copyright (C) 1992 Shayne Hughes, UC Davis, CA 95616
  7. ;
  8. ; This file is distributed under the terms listed in the document
  9. ; "copying.dj", available from DJ Delorie at the address above.
  10. ; A copy of "copying.dj" should accompany this file; if not, a copy
  11. ; should be available from where this file was obtained.  This file
  12. ; may not be distributed without a verbatim copy of "copying.dj".
  13. ;
  14. ; This file is distributed WITHOUT ANY WARRANTY; without even the implied
  15. ; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  16. ;--------------------------------------------------------------------------
  17.  
  18. ; NOTE: this file was formerly called STEALTH.ASM
  19. ; It seems that for once the industry is succeeding in manufacturing
  20. ; compatible graphics boards, as this driver, orginally written for a
  21. ; Diamond Stealth board seems to work unchanged on Orchid F1280 and
  22. ; similar S3 based boards, AND EVEN local bus S3 boards.
  23. ; Thanks to Shayne Hughes, we now have a paging routine for this
  24. ; driver. This allows direct memory access to the video RAM - although
  25. ; GRX is not using it.
  26.  
  27. _TEXT    segment byte public 'CODE'
  28. _TEXT    ends
  29. DGROUP  group    _TEXT,_DATA,_BSS
  30.     assume  cs:_TEXT,ds:DGROUP
  31. _DATA    segment word public 'DATA'
  32. d@    label    byte
  33. d@w    label    word
  34. _DATA    ends
  35. _BSS    segment word public 'BSS'
  36. b@    label    byte
  37. b@w    label    word
  38. _BSS    ends
  39. _TEXT    segment byte public 'CODE'
  40.     assume  cs:_TEXT,ds:DGROUP
  41.  
  42. include grdriver.inc
  43.  
  44. ;--------------------------------------------------------------------------
  45. ; DRIVER HEADER
  46. ;  The following entries MUST match the structure and constant
  47. ;  declarations in the file 'grdriver.h' of the GRX graphics library
  48. ;  The mode word should contain the following bitfields:
  49. ;     - the GRD_NEW_DRIVER bit set for any new format driver
  50. ;     - the adapter type field should be specified
  51. ;     - the memory size field should be specified
  52. ;     - the paging mode field should be specified
  53. ;  The mode set routine will OR in the plane bitfield as it will
  54. ;  change when different color number modes are requested.
  55. ;--------------------------------------------------------------------------
  56.  
  57.     dw    offset mode_set_routine
  58.     dw    offset paging_routine
  59. mode_W  dw    GRD_NEW_DRIVER+GRD_VGA+GRD_1024K+GRD_NO_RW
  60. ;
  61. ; The 'def_xx' fields are filled in by go32 from the corresponding
  62. ; fields of the 'GO32' environment variable
  63. ;
  64. def_tw  dw    80        ; text width
  65. def_th  dw    25        ; text height
  66. def_gw  dw    320        ; graphics width
  67. def_gh  dw    200        ; graphics height
  68. def_nc  dw    16        ; graphics colors
  69.     dw    offset driver_init_routine
  70.     dw    offset text_mode_table
  71.     dw    offset graphics_mode_table
  72.  
  73. ;
  74. ; Biggest text and graphics sizes
  75. ;
  76. Max_TW  equ    80
  77. Max_TH  equ    50
  78. Max_GWn equ    640        ; non interlaced!!!
  79. Max_GHn equ    480
  80. Max_GW  equ    640        ; may be interlaced
  81. Max_GH  equ    480
  82.  
  83.  
  84. ;--------------------------------------------------------------------------
  85. ; TABLE OF SUPPORTED TEXT MODES
  86. ;    - keep sorted by size
  87. ;    - end with an all 0 entry
  88. ;    - BIOS field = 0xff disables it
  89. ;    - fields:
  90. ;        width,  height, colors, BIOS#+  setup_procedure_index*256
  91. ;--------------------------------------------------------------------------
  92. text_mode_table        label word
  93.     dw    80,    25,    2,    007h +  00000h
  94.     dw    40,    25,    16,    001h +  00000h
  95.     dw    80,    25,       16,    003h +  00000h
  96.     dw    80,    28,       16,    003h +  00400h  ; 80x25 + reload 14 row font
  97.     dw    80,    50,       16,    003h +  00600h  ; 80x25 + reload 8 row font
  98.     dw    132,    25,       16,    109h +  00000h  ; VESA 109h mode
  99.     dw    132,    28,       16,    109h +  00400h  ; VESA 109h mode (132x25) + reload 14 row font
  100.     dw    132,    44,       16,    10ah +  00000h  ; VESA 10ah mode
  101.     dw    132,    50,       16,    109h +  00600h  ; VESA 109h mode (132x25) + reload 8 row font
  102.     dw    0,    0,        0,    000h +  00000h
  103.  
  104. ;--------------------------------------------------------------------------
  105. ; TABLE OF SUPPORTED GRAPHICS MODES
  106. ;    - keep sorted first by colors then by size
  107. ;    - end with an all 0 entry
  108. ;    - BIOS field = 0xff disables it
  109. ;    - fields:
  110. ;        width,  height, colors, BIOS#+  setup_procedure_index*256
  111. ;--------------------------------------------------------------------------
  112. graphics_mode_table    label word
  113.     dw    320,    200,    16,    00dh +  00000h
  114.     dw    640,    200,    16,    00eh +  00000h
  115.     dw    640,    350,    16,    010h +  00000h
  116.     dw    640,    480,      16,    012h +  00000h
  117.      dw    800,    600,    16,    002h +  00100h  ; VESA 102h mode
  118.      dw    320,    200,    256,    013h +  00000h
  119. ;    dw    640,    480,    256,    001h +  00200h  ; VESA S3 201h mode
  120. ;     dw    800,    600,    256,    003h +  00200h  ; VESA S3 203h mode
  121. ;     dw     1024,    768,    256,    005h +  00200h  ; VESA S3 205h mode
  122.      
  123.      dw    640,    480,    256,    001h +  00100h  ; VESA 101h mode
  124.      dw    800,    600,    256,    003h +  00100h  ; VESA 103h mode
  125.      dw     1024,    768,    256,    005h +  00100h  ; VESA 105h mode
  126.      dw     1280,   1024,    256,    007h +  00100h  ; VESA 105h mode
  127. ;       dw     1600,   1200,    256,    020h +  00100h  ; VESA 120h mode
  128.  
  129. ;     dw    320,    200,    32768,  00dh +  00100h  ; 15 bits
  130.      dw    640,    480,    32768,  010h +  00100h  ; 15 bits
  131.      dw    800,    600,    32768,  013h +  00100h  ; 15 bits
  132.      dw     1024,    768,    32768,  016h +  00100h  ; 15 bits
  133. ;    dw     1280,   1024,    32768,  019h +  00100h  ; 15 bits
  134.  
  135. ;     dw    320,    200,    0c010h,  00eh +  00100h  ; 16 bits
  136.      dw    640,    480,    0c010h,  011h +  00100h  ; 16 bits
  137.      dw    800,    600,    0c010h,  014h +  00100h  ; 16 bits
  138.      dw     1024,    768,    0c010h,  017h +  00100h  ; 16 bits
  139. ;    dw     1280,   1024,    0c010h,  01ah +  00100h  ; 16 bits
  140.  
  141. ;    dw    320,    200,    0c018h,  00eh +  00100h  ; 32 bits
  142.      dw    640,    480,    0c018h,  012h +  00100h  ; 32 bits
  143.      dw    800,    600,    0c018h,  015h +  00100h  ; 32 bits
  144. ;     dw     1024,    768,    0c018h,  018h +  00100h  ; 32 bits
  145. ;    dw     1280,   1024,    0c018h,  01bh +  00100h  ; 32 bits
  146.  
  147.      dw    0,      0,    0,    000h +  00000h
  148.  
  149. ;--------------------------------------------------------------------------
  150. ; TABLE OF SPECIAL SETUP PROCEDURES
  151. ;  You may need such procedures for:
  152. ;     -- reloading fonts on standard EGA or VGA for
  153. ;     higher resolution text modes
  154. ;     -- enable HiColor mode of some Super VGAs
  155. ;     -- Handle the parameter passing conventions of the VESA BIOS
  156. ;     -- put VGA into 256 color plane mode ("MODE X")
  157. ;     -- etc...
  158. ;  There should be one entry in the table for every non-zero
  159. ;  'setup_procedure_index' in the text and graphics mode tables.
  160. ;  The first entry in the table belongs to index 100h, and so on.
  161. ;  The special setup procedure is invoked via a near call.
  162. ;
  163. ;  Entry: DI=address of the mode record from the text or graphics
  164. ;      table to set up.
  165. ;
  166. ;  Exit:  Adapter configured
  167. ;      BX=driver mode word as it should be returned by the mode set
  168. ;         routine. Typically it involves picking up the mode word
  169. ;         from the header and OR-ing in the appropriate bitplane mode
  170. ;         bitfield. (This is not needed for text modes)
  171. ;      AX, CX, DX, SI can be trashed, PRESERVE DI!!!!
  172. ;
  173. ;  NOTE: This runs in real mode, but don't mess with the segment registers.
  174. ;--------------------------------------------------------------------------
  175. special_setup_table    label word
  176.     dw    offset  VESA_SVGA_mode_set    ; for 01xxh modes
  177.     dw    offset  VESA_S3_mode_set    ; for 02xxh accelerated S3 modes
  178.         dw      0
  179.     dw    offset  VGA_28_row_mode_set    ; for 28 row text modes
  180.     dw    offset  VGA_28_row_mode_set    ; for 28 row VESA text modes
  181.     dw    offset  VGA_50_row_mode_set    ; for 50 row text modes
  182.     dw    offset  VGA_50_row_mode_set    ; for 50 row VESA text modes
  183.  
  184. ;
  185. ; Routine to set up VGA 50 row mode
  186. ; interface is described above
  187. ;
  188. VGA_50_row_mode_set    proc    near
  189.     mov    ax,WORD PTR [di+6]    ; get base mode number
  190.     and    ah,1            ; clear setup proc index
  191.     je    std_50_mode
  192.     mov    bx,ax
  193.     mov    ax,4f02h
  194.     int    10h
  195.     cmp    ax,004fh        ; VESA error ?
  196.     je    mode_50_done
  197.     mov    ax,3            ; VESA error -- set 80x25 mode
  198. std_50_mode:
  199.     int    10h
  200. mode_50_done:
  201.     xor    bx,bx
  202.     mov    ax,1112h        ; load 8x8 font
  203.     int    10h
  204.     ret
  205. VGA_50_row_mode_set    endp
  206.  
  207. ;
  208. ; Routine to set up VGA 28 row mode
  209. ; interface is described above
  210. ;
  211. VGA_28_row_mode_set      proc     near
  212.     mov    ax,WORD PTR [di+6]    ; get base mode number
  213.     and    ah,1            ; clear setup proc index
  214.     je    std_28_mode
  215.     mov    bx,ax
  216.     mov    ax,4f02h
  217.     int    10h
  218.     cmp    ax,004fh        ; VESA error ?
  219.     je    mode_28_done
  220.     mov    ax,3                  ; VESA error -- set 80x25 mode
  221. std_28_mode:
  222.     int    10h
  223. mode_28_done:
  224.     xor    bx,bx
  225.     mov    ax,1111h        ; load 8x14 font
  226.     int    10h
  227.     ret
  228. VGA_28_row_mode_set     endp
  229.  
  230. ;
  231. ; Routine to set up VESA SVGA modes
  232. ; interface is described above
  233. ;
  234. VESA_SVGA_mode_set    proc      near
  235.     mov    ax,4f02h
  236.     mov    bx,WORD PTR [di+6]
  237.         push    di
  238.     int     10h
  239.         pop     di
  240.     mov     bx,0ffffh             ; error code
  241.     cmp     ax,004fh
  242.     jne       VESA_SVGA_done
  243.  
  244. VESA_SVGA_set_plane:
  245.      mov    bx,GRD_4_PLANES
  246.     cmp       WORD PTR [di+4],16        ; 16 colors ?
  247.     je         VESA_SVGA_done
  248.     mov        bx,GRD_8_PLANES
  249.     cmp        WORD PTR [di+4],256        ; 256 colors ?
  250.     je         VESA_SVGA_done
  251.     mov        bx,GRD_16_PLANES
  252.     cmp        WORD PTR [di+4],32768        ; 32K colors ?
  253.     je         VESA_SVGA_done
  254.     mov        bx,GRD_16_R_PLANES
  255.     cmp        WORD PTR [di+4],0c010h        ; 64K colors ?
  256.     je         VESA_SVGA_done
  257.     mov        bx,GRD_24_PLANES
  258.     cmp        WORD PTR [di+4],0c018h        ; 16M colors ?
  259.     je         VESA_SVGA_done
  260.     mov        bx,GRD_PLANE_MASK        ; something is wrong!!
  261.  
  262. VESA_SVGA_done:
  263.         or      bx,mode_W
  264.     ret
  265. VESA_SVGA_mode_set    endp
  266.  
  267. ; Routine to set up VESA S3 modes
  268. ; interface is described above
  269. ;
  270. VESA_S3_mode_set    proc    near
  271.     mov    ax,4f02h
  272.     mov    bx,WORD PTR [di+6]
  273.         push    di
  274.     int    10h
  275.         pop     di
  276.     mov    bx,0ffffh        ; error code
  277.     cmp     ax,004fh
  278.     jne     VESA_S3_done
  279.         call    VESA_SVGA_set_plane
  280.     xor     bx,(GRD_VGA XOR GRD_S3)
  281. VESA_S3_done:
  282.     ret
  283. VESA_S3_mode_set           endp
  284.  
  285.  
  286. ;--------------------------------------------------------------------------
  287. ; DRIVER INIT ROUTINE
  288. ;  called once after the driver is loaded
  289. ;  may do one or more of the followings:
  290. ;    - check for proper board type
  291. ;    - check amount of RAM on board, and:
  292. ;    -- update word in header to reflect correct amount
  293. ;    -- disable modes in the tables for which there is not enough RAM
  294. ;    - check for special equipment (HiColor DAC, etc...)
  295. ;
  296. ;  Entry: nothing
  297. ;
  298. ;  Exit:  AX=status:
  299. ;       non-zero: OK,
  300. ;       0: something went wrong (e.g. wrong adapter, etc..)
  301. ;      BX,CX,DX may be trashed
  302. ;
  303. ;  NOTE: This runs in real mode, but don't mess with the segment registers.
  304. ;--------------------------------------------------------------------------
  305. driver_init_routine    proc    far
  306.     push    di
  307.     push    es
  308.     sub    sp,256
  309.     mov    di,sp
  310.     mov    ax,ss
  311.     mov    es,ax
  312.     mov    ax,4f00h
  313.     int    10h        ; check for VESA BIOS
  314.     cmp    ax,004fh
  315.     jne    init_error
  316.     cmp    BYTE PTR es:[di+0],'V'
  317.     jne    init_error
  318.     cmp    BYTE PTR es:[di+1],'E'
  319.     jne    init_error
  320.     cmp    BYTE PTR es:[di+2],'S'
  321.     jne    init_error
  322.     cmp    BYTE PTR es:[di+3],'A'
  323.     jne    init_error
  324.     mov    ax,1        ; OK, VESA BIOS found
  325.     jmp    init_done
  326. init_error:
  327.     xor    ax,ax
  328. init_done:
  329.     add    sp,256
  330.     pop    es
  331.     pop    di
  332.     ret
  333. driver_init_routine    endp
  334.  
  335.  
  336. ;--------------------------------------------------------------------------
  337. ; MODE SET ROUTINE
  338. ;  sets up a text or graphics mode as close as possible to the one
  339. ;  reguested by the user with regard to number of colors and size.
  340. ;
  341. ;  Entry: AX=mode selection
  342. ;     0 = 80x25 text
  343. ;     1 = default text
  344. ;     2 = text CX cols by DX rows
  345. ;     3 = biggest text
  346. ;     4 = 320x200 graphics
  347. ;     5 = default graphics
  348. ;     6 = graphics CX width by DX height
  349. ;     7 = biggest non-interlaced graphics
  350. ;     8 = biggest graphics
  351. ;     9 = graphics BX colors, CX width by DX height
  352. ;
  353. ;  Exit: BX=driver mode flag
  354. ;     CX=width (in pixels or characters)
  355. ;     DX=height
  356. ;
  357. ;  NOTE: This runs in real mode, but don't mess with the segment registers.
  358. ;     YOU SHOULD NOT NEED TO CHANGE THIS ROUTINE AS IT IS PRETTY
  359. ;     MUCH TABLE DRIVEN
  360. ;--------------------------------------------------------------------------
  361. mode_set_routine        proc    far
  362.     push    ds
  363.     push    di
  364.     push    si
  365.     mov    si,cs
  366.     mov    ds,si
  367.     cmp    ax,9
  368.     jbe    DoIt
  369.     jmp    Exit
  370. DoIt:    add    ax,ax
  371.     mov    si,ax
  372.     jmp    WORD PTR mode_set_table[si]
  373. mode_set_table  label    word
  374.     dw    offset mode_0
  375.     dw    offset mode_1
  376.     dw    offset mode_2
  377.     dw    offset mode_3
  378.     dw    offset mode_4
  379.     dw    offset mode_5
  380.     dw    offset mode_6
  381.     dw    offset mode_7
  382.     dw    offset mode_8
  383.     dw    offset mode_9
  384. mode_0: mov    si,offset text_mode_table    ; 80x25 text
  385.     mov    bx,def_nc
  386.     mov    cx,80
  387.     mov    dx,25
  388.     jmp    Lookup
  389. mode_1: mov    si,offset text_mode_table    ; default text
  390.     mov    bx,def_nc
  391.     mov    cx,def_tw
  392.     mov    dx,def_th
  393.     jmp    Lookup
  394. mode_2: mov    si,offset text_mode_table    ; CX*DX text
  395.     mov    bx,def_nc
  396.     jmp    Lookup
  397. mode_3: mov    si,offset text_mode_table    ; biggest text
  398.     mov    bx,def_nc
  399.     mov    cx,Max_TW
  400.     mov    dx,Max_TH
  401.     jmp    Lookup
  402. mode_4: mov    si,offset graphics_mode_table    ; 320x200 graphics
  403.     mov    bx,def_nc
  404.     mov    cx,320
  405.     mov    dx,200
  406.     jmp    Lookup
  407. mode_5: mov    si,offset graphics_mode_table    ; default graphics
  408.     mov    bx,def_nc
  409.     mov    cx,def_gw
  410.     mov    dx,def_gh
  411.     jmp    Lookup
  412. mode_6: mov    si,offset graphics_mode_table    ; CX*DX graphics
  413.     mov    bx,def_nc
  414.     jmp    Lookup
  415. mode_7: mov    si,offset graphics_mode_table    ; biggest non-interlaced gr
  416.     mov    bx,def_nc
  417.     mov    cx,Max_GWn
  418.     mov    dx,Max_GHn
  419.     jmp    Lookup
  420. mode_8: mov    si,offset graphics_mode_table    ; biggest graphics
  421.     mov    bx,def_nc
  422.     mov    cx,Max_GW
  423.     mov    dx,Max_GH
  424.     jmp    Lookup
  425. mode_9: mov    si,offset graphics_mode_table    ; CX*DX graphics w/ BX colors
  426. ;
  427. ; At this point:
  428. ;   SI points to the table to search (text or graphics)
  429. ;   BX has colors
  430. ;   CX has width
  431. ;   DX has height
  432. ;
  433. Lookup: xor    ax,ax                ; last color number seen
  434. Find_C: cmp    [si+4],ax            ; last color number == this?
  435.     je     Same_C
  436.     jb    Prev_C                ; end of table -- use last color
  437.     cmp    BYTE PTR [si+6],0ffh        ; valid entry ?
  438.     je    Prev_C                ; not -- use last color
  439.     mov    ax,[si+4]            ; record color number
  440.     mov    di,si                ; start of entries w/ this color
  441.     cmp    ax,bx                ; enough colors ?
  442.     jae    Find_S
  443. Same_C: add    si,8
  444.     jmp    Find_C
  445. Prev_C: or    ax,ax                ; found any color at all?
  446.     je    Exit
  447. ;
  448. ; At this point:
  449. ;   DI points into the table to the first entry with the desired color
  450. ;      number (either it has enough colors or it is the highest color
  451. ;      number supported by the driver). Additionally, at least the
  452. ;      first (= smallest size) entry for this color is valid (has a
  453. ;      valid BIOS number).
  454. ;   AX has the color number adjusted for the driver
  455. ;   CX has width
  456. ;   DX has height
  457. ;
  458. Find_S: cmp    [di+4],ax            ; still the same color #?
  459.     jne    Prev_S
  460.     cmp    BYTE PTR [di+6],0ffh        ; valid entry ?
  461.     je    Prev_S
  462.     cmp    [di],cx
  463.     jb    Next_S
  464.     cmp    [di+2],dx
  465.     jae    GotIt
  466. Next_S: add    di,8
  467.     jmp    Find_S
  468. Prev_S: sub    di,8
  469. ;
  470. ; At this point:
  471. ;   DI points to the table entry we want to set up
  472. ;
  473. GotIt:  mov    ax,[di+6]            ; BIOS mode number
  474.     or     ah,ah                ; special ?
  475.     je    doBIOS
  476.     mov    al,ah
  477.     xor    ah,ah
  478.     dec    ax
  479.     add    ax,ax
  480.     mov    si,ax
  481.     call    WORD PTR special_setup_table[si]
  482.     jmp    RetVal
  483. doBIOS: int    10h
  484.     mov    bx,GRD_1_PLANE
  485.     cmp    WORD PTR [di+4],2        ; 2 colors ?
  486.      je     doFLAG
  487.      mov    bx,GRD_4_PLANES
  488.      cmp    WORD PTR [di+4],16        ; 16 colors ?
  489.      je     doFLAG
  490.      mov    bx,GRD_8_PLANES
  491.     cmp    WORD PTR [di+4],256        ; 256 colors ?
  492.     je     doFLAG
  493.     mov    bx,GRD_16_PLANES
  494.     cmp    WORD PTR [di+4],32768        ; 32K colors ?
  495.     je     doFLAG
  496.     mov    bx,GRD_PLANE_MASK        ; something is wrong!!
  497. doFLAG: or     bx,mode_W
  498. RetVal: mov    cx,[di]
  499.     mov    dx,[di+2]
  500. Exit:    pop    si
  501.     pop    di
  502.     pop    ds
  503.     ret
  504. mode_set_routine    endp
  505.  
  506.  
  507. ;--------------------------------------------------------------------------
  508. ; PAGING ROUTINE
  509. ;
  510. ;  Entry: AH=read page
  511. ;      AL=write page
  512. ;
  513. ;  Exit: VGA configured.
  514. ;     AX,BX,CX,DX,SI,DI may be trashed
  515. ;
  516. ;  NOTE: This runs in protected mode!  Don't mess with the segment registers!
  517. ;     This code must be relocatable and may not reference any data!
  518. ;--------------------------------------------------------------------------
  519.     assume  ds:nothing, es:nothing
  520.  
  521. paging_routine  proc     far
  522.     mov    cl,al        ; save for later
  523.     mov    ax,4838h    ; Unlock S3 extensioon 1
  524.     mov    dx,3d4h
  525.     out    dx,ax
  526.     mov    ax,0a539h    ; Unlock S3 extension 2
  527.     out    dx,ax
  528.     mov    al,31h        ; turn on  paging
  529.     out    dx,al
  530.      inc    dx
  531.     in    al,dx
  532.     or     al,1            ; enable bank register
  533.     out    dx,al
  534.     dec    dx   
  535.     mov    al,35h             ; index CRT Reg. Lock
  536.     out    dx,al
  537.     inc    dx           ; read CRT Reg. Lock
  538.     in    al,dx
  539.     and    al,0f0h        ; update with new bank, bank bits 0..3
  540.         mov     ah,cl
  541.         and     ah,0fh
  542.     or    al,ah
  543.     out    dx,al         ; write CRT Reg. Lock
  544.  
  545.     dec    dx
  546.     mov    al,51h             ; index CRT Reg. Lock
  547.     out    dx,al
  548.     inc    dx           ; read CRT Reg. Lock
  549.     in    al,dx
  550.     and    al,0f3h        ; update with new bank, bank bits 4..5
  551.         mov     ah,cl
  552.         and     ah,030h
  553.         shr     ah,1
  554.         shr     ah,1
  555.     or    al,ah
  556.     out    dx,al         ; write CRT Reg. Lock
  557.         
  558.     mov    ax,0038h    ; Lock S3 extension 1
  559.     dec    dx
  560.     out    dx,ax
  561.     mov    ax,5a39h    ; Lock S3 extension 2
  562.     out    dx,ax        
  563.     ret
  564. paging_routine  endp
  565.  
  566. _TEXT    ends
  567.     end
  568.  
  569.